home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 23 code / Documentary Synchronicity ƒ / Source ƒ / main.c < prev   
Encoding:
C/C++ Source or Header  |  1995-06-18  |  17.4 KB  |  747 lines  |  [TEXT/KAHL]

  1. /* 4567890123456789012345678901234567890123456789012345678901234567 */
  2. /*
  3.  * File:              main.c
  4.  * Author:            Mark H. Linton
  5.  * Creation Date:     2/4/95
  6.  * Modification Date: 
  7.  * Description:       A sample procedural shell for a typical 
  8.  *                    Macintosh appplication.
  9.  */
  10. #include <Dialogs.h>
  11. #include <Memory.h>
  12. #include <Errors.h>
  13. #include <AppleEvents.h>
  14. #include <Desk.h>
  15. #include <ToolUtils.h>
  16. #include <StandardFile.h>
  17. #include <Resources.h>
  18. #include <Gestalt.h>
  19.  
  20. #include "main.h"
  21. #include "Document.h"
  22.  
  23. #include "Toolbox.h"
  24. #include "Splash.h"
  25. #include "AERequired.h"
  26. #include "HasRequiredFeatures.h"
  27. #include "About.h"
  28. #include "ProcessInfo.h"
  29. #include "EvenMoreFiles.h"
  30. #include "SaveSafely.h"
  31.  
  32. #include "DSDocumentList.h"
  33. #include "DSDocumentMenu.h"
  34. #include "DSSyncWindowWithFile.h"
  35. #include "DSPopUpNavigation.h"
  36.  
  37. #include "ResourceDefinitions.h"
  38.  
  39. enum {
  40.     iAbout = 1,
  41.     iNew = 1,
  42.     iOpen = 2,
  43.     iClose = 4,
  44.     iSave = 5,
  45.     iSaveAs = 6,
  46.     iRevert = 7,
  47.     iPageSetup = 9,
  48.     iPrint = 10,
  49.     iQuit = 12
  50. };
  51.  
  52. static OSErr InstallMenuBar(void);
  53. static OSErr AdjustMenus(void);
  54. static OSErr AdjustFileMenu(void);
  55. static OSErr EventLoop(void);
  56. static OSErr DoMouseDown(EventRecord *anEvent);
  57. static OSErr DoCommand(long aMenuSelection);
  58. static OSErr DoFileCommand(short anItemNumber);
  59. static long SleepTime(void);
  60.  
  61. struct ApplicationGlobals {
  62.     Boolean done;
  63. } g; /* do not clutter global name space, Re: qd.thePort */
  64.  
  65. #define kFrontSleep (10) /* 1/6 of a second */
  66. #define kBackSleep (600) /* 10 seconds */
  67.  
  68. #define kDontSave (3)
  69.  
  70. int main(void) {
  71.     OSErr theError = noErr;
  72.  
  73.     theError = InitToolbox();
  74.     if ((theError == noErr) && (HasRequiredFeatures())) {
  75.         if (theError == noErr) {
  76.             Splash(rSplashScreen);
  77.             theError = DSInitDocumentList();
  78.         }
  79.         if (theError == noErr) {
  80.             theError = InstallMenuBar();
  81.         }
  82.         if (theError == noErr) {
  83.             theError = InstallRequiredAppleEvents();
  84.         }
  85.         if (theError == noErr) {
  86.             UnSplash(true);
  87.             InitCursor();
  88.             theError = EventLoop();
  89.         }
  90.     } else if (theError == noErr) {
  91.         (void)Alert(rMissingFeatureAlert, nil);
  92.     }
  93.     if (theError != noErr) ReportError(theError);
  94.     return theError;
  95. }
  96.  
  97. OSErr InstallMenuBar(void) {
  98.     Handle theMenuBar = nil;
  99.     OSErr theError = noErr;
  100.     MenuHandle theAppleMenu = nil;
  101.  
  102.     theMenuBar = GetNewMBar(rMenuBar);
  103.     if (theMenuBar != nil) {
  104.         SetMenuBar(theMenuBar);
  105.         DisposeHandle(theMenuBar);
  106.         DSInitDocumentMenu(mDocument);
  107.         theAppleMenu = GetMenuHandle(mApple);
  108.         if (theAppleMenu != nil) {
  109.             AppendResMenu(theAppleMenu, 'DRVR');
  110.             theError = AdjustMenus();
  111.         } else {
  112.             theError = memFullErr;
  113.         }
  114.     }
  115.     if (theError == noErr) {
  116.         DrawMenuBar();
  117.     }
  118.     return theError;
  119. }
  120.  
  121. OSErr AdjustMenus(void) {
  122.     OSErr theError = noErr;
  123.     
  124.     theError = AdjustFileMenu();
  125.     DSAdjustDocumentMenu();
  126.     return theError;
  127. }
  128.  
  129. OSErr AdjustFileMenu(void) {
  130. #if STRICT_WINDOWS
  131.     WindowRef theWindow;
  132. #else
  133.     WindowPtr theWindow;
  134. #endif
  135.     MenuHandle theMenu;
  136.     short theFRefNum;
  137.     OSErr theError = noErr;
  138.     
  139.     theMenu = GetMenuHandle(mFile);
  140.     if (theMenu != nil) {
  141.         EnableItem(theMenu, iQuit);
  142.         EnableItem(theMenu, iNew);
  143.         EnableItem(theMenu, iOpen);
  144.         theWindow = FrontWindow();
  145.         if (!DSInDocumentList(theWindow)) {
  146.             DisableItem(theMenu, iSaveAs);
  147.             DisableItem(theMenu, iClose);
  148.             DisableItem(theMenu, iSave);
  149.         } else {
  150.             EnableItem(theMenu, iSaveAs);
  151.             EnableItem(theMenu, iClose);
  152.             theError = 
  153.                 DSGetWindowDFRefNum(FrontWindow(), &theFRefNum);
  154.             if ((theError == noErr) && (theFRefNum != 0) && 
  155.                     DSIsWindowDirty(FrontWindow())) {
  156.                 EnableItem(theMenu, iSave);
  157.                 EnableItem(theMenu, iRevert);
  158.             } else {
  159.                 DisableItem(theMenu, iSave);
  160.                 DisableItem(theMenu, iRevert);
  161.             }
  162.         }
  163.     } else {
  164.         theError = menuPrgErr;
  165.     }
  166.     return theError;
  167. }
  168.  
  169. OSErr EventLoop(void) {
  170.     RgnHandle theCursorRegion = NewRgn();
  171.     EventRecord theEvent;
  172.     OSErr theError = noErr;
  173.     Boolean    gotEvent;
  174.     
  175.     g.done = false;
  176.     while (!g.done && (theError == noErr)) {
  177.         gotEvent = WaitNextEvent(everyEvent, &theEvent, SleepTime(), 
  178.             theCursorRegion);
  179.         if (gotEvent) {
  180.             CheckGrowZone();
  181.             theError = DoEvent(&theEvent);
  182.         }
  183.         if (theError == noErr) {
  184.             theError = DSSyncWindowsWithFiles(kDontForceSynchronization);
  185.         }
  186.     }
  187.     DisposeRgn(theCursorRegion);
  188.     return theError;
  189. }
  190.  
  191. pascal OSErr DoEvent(EventRecord *anEvent) {
  192.     OSErr theError = noErr;
  193.     
  194.     switch (anEvent->what) {
  195.     case keyDown:
  196.     case autoKey:
  197.         if ((anEvent->modifiers & cmdKey) != 0) {
  198.             AdjustMenus();
  199.             DoCommand(MenuKey(anEvent->message & charCodeMask));
  200.         } else {
  201. /*            DoKeyDown(anEvent); */
  202.         }
  203.         break;
  204.     case mouseDown:
  205.         theError = DoMouseDown(anEvent);
  206.         break;
  207.     case activateEvt:
  208. #if STRICT_WINDOWS
  209.         if (DSInDocumentList((WindowRef)anEvent->message)) {
  210.             DrawGrowIcon((WindowRef)anEvent->message);
  211.         }
  212. #else
  213.         if (DSInDocumentList((WindowPtr)anEvent->message)) {
  214.             DrawGrowIcon((WindowPtr)anEvent->message);
  215.         }
  216. #endif
  217.         break;
  218.     case osEvt:
  219.         if (((anEvent->message >> 24) & 0xff) == suspendResumeMessage) {
  220.             if (DSInDocumentList(FrontWindow())) {
  221.                 DrawGrowIcon(FrontWindow());
  222.             }
  223.             theError = DSSyncWindowsWithFiles(kForceSynchronization);
  224.         }
  225.         break;
  226.     case updateEvt:
  227. #if STRICT_WINDOWS
  228.         BeginUpdate((WindowRef)anEvent->message);
  229.         DoDrawDocument((WindowRef)anEvent->message);
  230.         DrawGrowIcon((WindowRef)anEvent->message);
  231.         EndUpdate((WindowRef)anEvent->message);
  232. #else
  233.         BeginUpdate((WindowPtr)anEvent->message);
  234.         DoDrawDocument((WindowPtr)anEvent->message);
  235.         DrawGrowIcon((WindowPtr)anEvent->message);
  236.         EndUpdate((WindowPtr)anEvent->message);
  237. #endif
  238.         break;
  239.     case diskEvt:
  240.         DoDiskEvent(anEvent->message);
  241.         break;
  242.     case kHighLevelEvent:
  243.         theError = AEProcessAppleEvent(anEvent);
  244.         break;
  245.     }
  246.     return theError;
  247. }
  248.  
  249. OSErr DoMouseDown(EventRecord *anEvent) {
  250. #if STRICT_WINDOWS
  251.     WindowRef theWindow;
  252. #else
  253.     WindowPtr theWindow;
  254. #endif
  255.     short theWindowPart = DSFindWindow(anEvent->where, &theWindow);
  256.     RgnHandle theGrayRegion;
  257.     OSErr theError = noErr;
  258.     
  259.     switch (theWindowPart) {
  260.     case inMenuBar:
  261.         theError = AdjustMenus();
  262.         if (theError == noErr) {
  263.             theError = DoCommand(MenuSelect(anEvent->where));
  264.         }
  265.         break;
  266.     case inSysWindow:
  267. #if STRICT_WINDOWS
  268.         SystemClick(anEvent, (WindowPtr)GetWindowPort(theWindow));
  269. #else
  270.         SystemClick(anEvent, theWindow);
  271. #endif
  272.         break;
  273.     case inDrag:
  274.         theGrayRegion = GetGrayRgn();
  275.         DragWindow(theWindow, anEvent->where, 
  276.             &(**theGrayRegion).rgnBBox);
  277.         break;
  278.     case inContent:
  279.         if (theWindow != FrontWindow()) {
  280.             SelectWindow(theWindow);
  281.         } else {
  282.             DoContentClick(theWindow, anEvent);
  283.         }
  284.         break;
  285.     case inGrow:
  286.         if (DSInDocumentList(theWindow)) {
  287.             Rect theLimitRect = { 68, 110, 32767, 32767 };
  288.             long theGrowSize = 
  289.                 GrowWindow(theWindow, anEvent->where, &theLimitRect);
  290.         
  291.             if (theGrowSize != 0) {
  292.                 GrafPtr theCurrentPort;
  293.                 
  294.                 GetPort(&theCurrentPort);
  295. #if STRICT_WINDOWS
  296.                 SetPortWindowPort(theWindow);
  297.                 EraseRect(&GetWindowPort(theWindow)->portRect);
  298. #else
  299.                 SetPort(theWindow);
  300.                 EraseRect(&theWindow->portRect);
  301. #endif
  302.                 SizeWindow(theWindow, LoWord(theGrowSize), 
  303.                     HiWord(theGrowSize), true);
  304. #if STRICT_WINDOWS
  305.                 InvalRect(&GetWindowPort(theWindow)->portRect);
  306. #else
  307.                 InvalRect(&theWindow->portRect);
  308. #endif
  309.                 SetPort(theCurrentPort);
  310.             }
  311.         }
  312.         break;
  313.     case inGoAway:
  314.         if (TrackGoAway(theWindow, anEvent->where)) {
  315.             theError = DoCloseCommand(theWindow, true);
  316.             if ((theError == noErr) && 
  317.                     ((anEvent->modifiers & optionKey) != 0)) {
  318.                 for (theWindow = DSFirstWindow(); 
  319.                         (theWindow != nil) && (theError == noErr); 
  320.                         theWindow = DSFirstWindow()) {
  321.                     theError = DoCloseCommand(theWindow, true);
  322.                 }
  323.             }
  324.             if (theError == userCanceledErr) theError = noErr;
  325.         }
  326.         break;
  327.     case inZoomIn:
  328.     case inZoomOut:
  329.         if (TrackBox(theWindow, anEvent->where, theWindowPart)) {
  330.             GrafPtr theCurrentPort;
  331.             
  332.             GetPort(&theCurrentPort);
  333. #if STRICT_WINDOWS
  334.             SetPortWindowPort(theWindow);
  335.             EraseRect(&GetWindowPort(theWindow)->portRect);
  336. #else
  337.             SetPort(theWindow);
  338.             EraseRect(&theWindow->portRect);
  339. #endif
  340.             ZoomWindow(theWindow, theWindowPart, 
  341.                 (theWindow == FrontWindow()));
  342.             SetPort(theCurrentPort);
  343.         }
  344.         break;
  345.     }
  346.     return theError;
  347. }
  348.  
  349. OSErr DoCommand(long aMenuSelection) {
  350.     OSErr theError = noErr;
  351.     
  352.     switch (HiWord(aMenuSelection)) {
  353.     case mApple:
  354.         if (LoWord(aMenuSelection) == iAbout) {
  355.             DoAbout(rAbout);
  356.         } else {
  357.             Str255 theItemName;
  358.             
  359.             GetMenuItemText(GetMenuHandle(mApple), 
  360.                 LoWord(aMenuSelection), theItemName);
  361.             (void)OpenDeskAcc(theItemName);
  362.         }
  363.         break;
  364.     case mFile:
  365.         theError = DoFileCommand(LoWord(aMenuSelection));
  366.         break;
  367.     case mDocument:
  368.         DSDoDocumentCommand(LoWord(aMenuSelection));
  369.         break;
  370.     }
  371.     HiliteMenu(0);
  372.     
  373.     return theError;
  374. }
  375.  
  376. OSErr DoFileCommand(short anItemNumber) {
  377.     OSErr theError = noErr;
  378.     StandardFileReply theReply;
  379.     SFTypeList theTypeList = { '.oO~' };
  380.     
  381.     switch (anItemNumber) {
  382.     case iNew:
  383.         theError = DoNewCommand();
  384.         break;
  385.     case iOpen:
  386.         StandardGetFile(nil, 1, theTypeList, &theReply);
  387.         if (theReply.sfGood) {
  388.             theError = DoOpenCommand(&theReply.sfFile);
  389.         }
  390.         break;
  391.     case iClose:
  392.         theError = DoCloseCommand(FrontWindow(), true);
  393.         break;
  394.     case iSave:
  395.         theError = DoSave(FrontWindow());
  396.         break;
  397.     case iSaveAs:
  398.         theError = DoSaveAsCommand();
  399.         break;
  400.     case iRevert:
  401.         theError = DoRevertCommand(FrontWindow());
  402.         break;
  403.     case iQuit:
  404.         theError = DoQuit();
  405.         break;
  406.     }
  407.     if (theError == userCanceledErr) {
  408. /*
  409.  * If the user cancelled, whatever action was going to
  410.  * occur has already been handled.
  411.  */
  412.         theError = noErr;
  413.     }
  414.     return theError;
  415. }
  416.  
  417. pascal OSErr DoNewCommand(void) {
  418. #if STRICT_WINDOWS
  419.     WindowRef theWindow;
  420. #else
  421.     WindowPtr theWindow;
  422. #endif
  423.     OSErr theError = noErr;
  424.     long theVersion;
  425.     
  426. #if 0
  427.     if (HasFeature(gestaltQuickdrawFeatures, gestaltHasColor)) {
  428.     /*
  429.      * You might think that this was the correct way to check for the
  430.      * presence of Color QuickDraw--and hence the ability to use routines
  431.      * like GetNewCWindow instead of GetNewWindow-- but, you would be wrong.
  432.      *
  433.      * This call returns true on a Macintosh SE running System 7.5, but the
  434.      * GetNewCWindow trap is, in fact, not available on that machine.
  435.      *
  436.      * There is a note in "Inside Macintosh: Imaging with QuickDraw," in the
  437.      * section "Using Color QuickDraw," where it says:
  438.      *
  439.      *   "When testing for the existence of Color QuickDraw, your 
  440.      *    application should test the response to the 
  441.      *    gestaltQuickDrawVersion selector (rather than test for the result 
  442.      *    gestaltHasColor, which is unreliable, from the
  443.      *    gestaltQuickDrawFeatures selector)."
  444.      *
  445.      * Heed this advice.
  446.      */
  447. #else
  448.     /*
  449.      * Check the QuickDraw version instead. Like this:
  450.      */
  451.     theError = Gestalt(gestaltQuickdrawVersion, &theVersion);
  452.     if ((theError == noErr) && (theVersion > gestaltOriginalQD)) {
  453. #endif
  454.         theWindow = GetNewCWindow(rDocWindow, nil, kInFront);
  455.     } else {
  456.         if (theError != noErr) {
  457.             /*
  458.              * We will assume that if an error occurred, it was just a problem 
  459.              * with Gestalt--that the program is OK, but we probably do not 
  460.              * have Color QuickDraw. We could set a breakpoint here to 
  461.              * investigate, if we really wanted to (i.e. - THIS SHOULD NEVER
  462.              * HAPPEN =^).
  463.              */
  464.             theError = noErr;
  465.         }
  466.         theWindow = GetNewWindow(rDocWindow, nil, kInFront);
  467.     }
  468.     if (theWindow != nil) {
  469.         theError = DSAddWindow(theWindow);
  470.         if (theError == noErr) {
  471.             theError = DSSetCreatorAndFileType(theWindow, 
  472.                 GetSignature(), GetSignature());
  473.         }
  474.         if (theError == noErr) {
  475.             theError = DSSetWindowDFRefNum(theWindow, 0);
  476.         }
  477.         if (theError == noErr) {
  478.             ShowWindow(theWindow);
  479.             DSAdjustDocumentMenu();
  480.         }
  481.     } else {
  482.         theError = memFullErr;
  483.     }
  484.     return theError;
  485. }
  486.  
  487. pascal OSErr DoOpenCommand(FSSpec *aFile) {
  488.     OSErr theError;
  489. #if STRICT_WINDOWS
  490.     WindowRef theWindow;
  491. #else
  492.     WindowPtr theWindow;
  493. #endif
  494.     short theFRefNum;
  495.     
  496.     if (DSFileInDocumentList(aFile, &theWindow)) {
  497.         SelectWindow(theWindow);
  498.     } else {
  499.         theError = DoNewCommand();
  500.         if (theError == noErr) {
  501.             theError = FSpOpenDF(aFile, fsCurPerm, &theFRefNum);
  502.             if (theError == permErr) {
  503.                 ParamText(aFile->name, kNullString, kNullString, kNullString);
  504.                 (void)StopAlert(rPermErrAlert, nil);
  505.                 (void)DoCloseCommand(FrontWindow(), false);
  506.             }
  507.         }
  508.         if (theError == noErr) {
  509.             theWindow = FrontWindow();
  510.             theError = DSSetWindowDFRefNum(theWindow, theFRefNum);
  511.         }
  512.         if (theError == noErr) {
  513.             theError = DoReadDocument(theWindow);
  514.         }
  515.         if (theError == noErr) {
  516.             SetWTitle(theWindow, aFile->name);
  517.         }
  518.     }
  519.     DSAdjustDocumentMenu();
  520.     return theError;
  521. }
  522.  
  523. #if STRICT_WINDOWS
  524. OSErr DoCloseCommand(WindowRef aWindow, Boolean notify) {
  525. #else
  526. OSErr DoCloseCommand(WindowPtr aWindow, Boolean notify) {
  527. #endif
  528.     short theFRefNum;
  529.     OSErr theError = noErr;
  530.     short theResponse;
  531.     Str255 theTitle;
  532.     Boolean proceed;
  533.     
  534.     if (DSInDocumentList(aWindow)) {
  535.         if (DSIsWindowDirty(aWindow) && notify) {
  536.             GetWTitle(aWindow, theTitle);
  537.             ParamText(theTitle, kNullString, kNullString, kNullString);
  538.             theResponse = StopAlert(rCloseDirtyAlert, nil);
  539.             switch (theResponse) {
  540.             case ok: /* Save */
  541.                 theError = DSGetWindowDFRefNum(aWindow, &theFRefNum);
  542.                 proceed = false;
  543.                 if (theError == noErr) {
  544.                     if (theFRefNum == 0) {
  545.                         theError = DoSaveAsCommand();
  546.                     } else {
  547.                         theError = DoSave(aWindow);
  548.                     }
  549.                     if (theError != noErr) {
  550.                         proceed = false;
  551.                     } else {
  552.                         proceed = true;
  553.                     }
  554.                 }
  555.                 break;
  556.             case cancel:
  557.                 proceed = false;
  558.                 theError = userCanceledErr;
  559.                 break;
  560.             case kDontSave:
  561.                 proceed = true;
  562.                 break;
  563.             }
  564.         } else {
  565.             proceed = true;
  566.         }
  567.         if ((theError == noErr) && (proceed)) {
  568.             theError = DSGetWindowDFRefNum(aWindow, &theFRefNum);
  569.             if ((theError == noErr) && (theFRefNum != 0)) {
  570.                 theError = FSClose(theFRefNum);
  571.             }
  572.             if (theError == noErr) {
  573.                 theError = DSGetWindowRFRefNum(aWindow, &theFRefNum);
  574.                 if ((theError == noErr) && (theFRefNum != 0)) {
  575.                     CloseResFile(theFRefNum);
  576.                     theError = ResError();
  577.                 }
  578.             }
  579.             if (theError == noErr) {
  580.                 theError = DoRemoveDocumentData(aWindow);
  581.             }
  582.             if (theError == noErr) {
  583.                 theError = DSRemoveWindow(aWindow);
  584.             }
  585.             if (theError == noErr) {
  586.                 DisposeWindow(aWindow);
  587.             }
  588.         }
  589.         DSAdjustDocumentMenu();
  590.     }
  591.     return theError;
  592. }
  593.  
  594. #if STRICT_WINDOWS
  595. OSErr DoRevertCommand(WindowRef aWindow) {
  596. #else
  597. OSErr DoRevertCommand(WindowPtr aWindow) {
  598. #endif
  599.     short theFRefNum;
  600.     OSErr theError = noErr;
  601.     short theResponse;
  602.     Str255 theTitle;
  603.     FSSpec theFile;
  604.     
  605.     if (DSInDocumentList(aWindow)) {
  606.         GetWTitle(aWindow, theTitle);
  607.         ParamText(theTitle, kNullString, kNullString, kNullString);
  608.         theResponse = StopAlert(rRevertAlert, nil);
  609.         if (theResponse == ok) {
  610.             theError = DSGetWindowDFRefNum(aWindow, &theFRefNum);
  611.             if ((theError == noErr) && (theFRefNum != 0)) {
  612.                 theError = GetFileSpec(theFRefNum, &theFile);
  613.                 if (theError == noErr) {
  614.                     theError = FSClose(theFRefNum);
  615.                 }
  616.                 if (theError == noErr) {
  617.                     theError = DoRemoveDocumentData(aWindow);
  618.                 }
  619.                 if (theError == noErr) {
  620.                     theError = DSRemoveWindow(aWindow);
  621.                 }
  622.                 if (theError == noErr) {
  623.                     DisposeWindow(aWindow);
  624.                 }
  625.                 if (theError == noErr) {
  626.                     theError = DoOpenCommand(&theFile);
  627.                 }
  628.             }
  629.         }
  630.     }
  631.     return theError;
  632. }
  633.  
  634. #if STRICT_WINDOWS
  635. OSErr DoSave(WindowRef aWindow) {
  636. #else
  637. OSErr DoSave(WindowPtr aWindow) {
  638. #endif
  639.     OSErr theError = noErr;
  640.     short theDFRefNum;
  641.     
  642.     theError = DSGetWindowDFRefNum(aWindow, &theDFRefNum);
  643.     if (theError == noErr) {
  644.         theError = SaveSafely(aWindow, nil, 0, DoWriteDocument, nil);
  645.     }
  646.     if (theError == noErr) {
  647.         theError = DSWindowClean(aWindow);
  648.     }
  649.  
  650.     return theError;
  651. }
  652.  
  653. OSErr DoSaveAsCommand(void) {
  654. #if STRICT_WINDOWS
  655.     WindowRef theWindow;
  656. #else
  657.     WindowPtr theWindow;
  658. #endif
  659.     StandardFileReply theReply;
  660.     OSErr theError = noErr;
  661.     Str255 prompt = "\pSave As:", defaultName = "\pUntitled";
  662.     short theFRefNum;
  663.     OSType theCreator, theFileType;
  664.  
  665.     theWindow = FrontWindow();
  666.     if (DSInDocumentList(theWindow)) {
  667.         theError = DSGetWindowDFRefNum(theWindow, &theFRefNum);
  668.         if ((theError == noErr) && (theFRefNum != 0)) {
  669.             GetWTitle(theWindow, defaultName);
  670.         }
  671.         StandardPutFile(prompt, defaultName, &theReply);
  672.         if (theReply.sfGood) {
  673.             if ((theError == noErr) && (theFRefNum != 0)) {
  674.                 theError = FSClose(theFRefNum); 
  675.             }
  676.             if ((theError == noErr) && (theReply.sfReplacing)) {
  677.                 theError = FSpDelete(&theReply.sfFile);
  678.             }
  679.             if (theError == noErr) {
  680.                 theError = DSGetCreatorAndFileType(theWindow, 
  681.                     &theCreator, &theFileType);
  682.             }
  683.             if (theError == noErr) {
  684.                 theError = FSpCreate(&theReply.sfFile, theCreator, 
  685.                     theFileType, theReply.sfScript);
  686.             }
  687.             if (theError == noErr) {
  688.                 theError = FSpOpenDF(&theReply.sfFile, fsCurPerm, 
  689.                     &theFRefNum);
  690.             }
  691.             if (theError == noErr) {
  692.                 theError = DSSetWindowDFRefNum(theWindow, theFRefNum);
  693.             }
  694.             if (theError == noErr) {
  695.                 theError = DoWriteDocument(theWindow, theFRefNum);
  696.             }
  697.             if (theError == noErr) {
  698.                 SetWTitle(theWindow, theReply.sfFile.name);
  699.                 theError = DSWindowClean(theWindow);
  700.             }
  701.         } else {
  702.             theError = userCanceledErr;
  703.         }
  704.     } else {
  705.         theError = paramErr;
  706.     }
  707.     DSAdjustDocumentMenu();
  708.     
  709.     return theError;
  710. }
  711.  
  712. pascal OSErr DoQuit(void) {
  713.     OSErr theError = noErr;
  714. #if STRICT_WINDOWS
  715.     WindowRef theWindow, theNextWindow;
  716. #else
  717.     WindowPtr theWindow, theNextWindow;
  718. #endif
  719.     
  720.     theWindow = DSFirstWindow();
  721.     while ((theWindow != nil) && (theError != userCanceledErr)) {
  722.         theNextWindow = DSNextWindow(theWindow);
  723.         theError = DoCloseCommand(theWindow, true);
  724.         theWindow = theNextWindow;
  725.     }
  726.     if (theError == userCanceledErr) {
  727.         theError = noErr;
  728.     } else {
  729.         g.done = true;
  730.     }
  731.     return theError;
  732. }
  733.  
  734. long SleepTime(void) {
  735.     OSErr theError;
  736.     long theSleepTime;
  737.     Boolean inBackground;
  738.     
  739.     theError = InBackground(&inBackground);
  740.     if ((theError == noErr) && (inBackground)) {
  741.         theSleepTime = kBackSleep;
  742.     } else {
  743.         theSleepTime = kFrontSleep;
  744.     }
  745.     return theSleepTime;
  746. }
  747.